package com.example.testnt;

import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

public class LocalEchoActivity extends AbstractEchoActivity {

    private EditText messageEdit;

    public LocalEchoActivity() {
        super(R.layout.activity_local_echo);
    }

    public LocalEchoActivity(int layoutID) {
        super(R.layout.activity_local_echo);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        messageEdit = findViewById(R.id.message_edit);

    }

    @Override
    protected void onStartButtonClicked() {

        String name = portEdit.getText().toString();
        String message = messageEdit.getText().toString();

        if ((name.length() > 0) && (message.length() > 0)) {

            String socketName;
            if (isFilesystemSocket(name)) {

                File file = new File(getFilesDir(), name);
                socketName = file.getAbsolutePath();
            } else {
                socketName = name;
            }

            ServerTask serverTask = new ServerTask(startButton, logView, socketName);
            serverTask.start();


            ClientTask clientTask = new ClientTask(socketName, message);
            clientTask.start();
        }


    }


    /**
     * 检查名称是否是filesystem socket
     *
     * @param name
     * @return
     */
    private boolean isFilesystemSocket(String name) {

        return name.startsWith("/");
    }


    /**
     * 启动本地unix socket 服务器
     */
    private native void nativeStartLocalServer(String name) throws Exception;

    /**
     * 启动本地UNix socket客户端
     */
    private void startLocalClient(String name, String message) throws Exception {


        LocalSocket clientSocket = new LocalSocket();

        try {
            LocalSocketAddress.Namespace namespace;
            if (isFilesystemSocket(name)) {
                namespace = LocalSocketAddress.Namespace.FILESYSTEM;
            } else {
                namespace = LocalSocketAddress.Namespace.ABSTRACT;
            }
            //new本地socket地址
            LocalSocketAddress address = new LocalSocketAddress(name, namespace);
            //连接
            logMessage("客户端连接到" + name);
            clientSocket.connect(address);
            logMessage("客户端连接成功");

            byte[] messageBytes = message.getBytes();
            logMessage("客户端发送消息");
            OutputStream outputStream = clientSocket.getOutputStream();
            outputStream.write(messageBytes);
            logMessage("客户端发送" + messageBytes.length + "字节:" + message);

            //从socket中接受信息
            logMessage("客户端接受数据");
            InputStream inputStream = clientSocket.getInputStream();
            int readSize = inputStream.read(messageBytes);

            String receivedMessage = new String(messageBytes, 0, readSize);
            logMessage("客户端接收" + readSize + "字节：" + receivedMessage);

            outputStream.close();
            inputStream.close();
        } finally {
            clientSocket.close();
        }
    }

    /**
     * 服务器
     */
    private class ServerTask extends AbstractEchoTask {

        private final String name;

        protected ServerTask(Button startButton, TextView logView, String name) {
            super(startButton, logView);
            this.name = name;
        }

        @Override
        protected void onBackground() {

            logMessage("开始服务");
            try {

                nativeStartLocalServer(name);

            } catch (Exception e) {

                logMessage(e.getMessage());
            }

            logMessage("服务终止");
        }
    }


    private class ClientTask extends Thread {

        private final String name;

        private final String message;

        public ClientTask(String name, String message) {

            this.name = name;
            this.message = message;
        }


        @Override
        public void run() {

            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logMessage("客户端开始");

            try {
                startLocalClient(name, message);
            } catch (Exception e) {

                logMessage(e.getMessage());
            }
            logMessage("客户端终止");
        }
    }
}
